﻿using System;
using NUnit.Framework;

namespace DirectoryCleaner.Tests
{
    /// <summary>
    /// Tests for Parser.
    /// </summary>
    [TestFixture]
    public class ParserTest
    {
        /// <summary>
        /// Check to see that the correct exception is thrown when args is null.
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ArgsNullTest()
        {
            Parser actual = new Parser(null);
        }

        /// <summary>
        /// Check to make sure that the correct exception is thrown when the user doesn't provide any flags (args).
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentException), ExpectedMessage="Please specify some flag arguments.")]
        public void NoFlagsSpecifiedTest()
        {
            string[] input = { };
            Parser actual = new Parser(input);
        }

        /// <summary>
        /// Check to make sure the tokens are broken down correctly.
        /// </summary>
        [Test]
        public void PreserveTest()
        {
            string[] expected = { ".cs", ".csproj" };
            string[] input = { "/preserve:.cs;.csproj" };

            Parser parser = new Parser(input);
            parser.Parse();

            string[] actual = parser.Extensions;

            CollectionAssert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Check to see that the correct exception is thrown when using an unrecognized flag.
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentException), ExpectedMessage="Unrecognized flag: /joke:")]
        public void UnregonizedFlagTest()
        {
            string[] input = { "/joke:.cs;.csproj" };
            Parser actual = new Parser(input);

            actual.Parse();
        }

        /// <summary>
        /// Check to make sure the correct exception if thrown if a flag has no args.
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Please specify args for flag: /preserve:")]
        public void FlagNoArgsTest()
        {
            string[] input = { "/preserve:" };
            Parser parser = new Parser(input);

            parser.Parse();
        }

        /// <summary>
        /// Check to make sure the correct exception is thrown when the input is structured incorectly, e.g.
        /// /preserve .cs;.csproj
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Incorrectly structured input.")]
        public void IncorrectlyStructuredInputTest()
        {
            string[] input = { "/preserve", ".cs;.csproj" };
            Parser actual = new Parser(input);

            actual.Parse();
        }

        /// <summary>
        /// Check to see that the directory is correct.
        /// </summary>
        [Test]
        public void DirTest()
        {
            string[] input = { "/dir:c:\test", "/preserve:.cs" };
            Parser actual = new Parser(input);

            actual.Parse();

            Assert.AreEqual("c:\test", actual.Directory);
        }

        /// <summary>
        /// Check to make sure that the correct exception is thrown if /preserve: is not defined.
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Flag: /preserve: must be specified.")]
        public void PreserveRequiredTest()
        {
            string[] input = { @"/dir:c:\" };
            Parser actual = new Parser(input);

            actual.Parse();
        }
    }
}
